home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Add-Ons
/
After Dark
/
Twist 1.0b1
/
FindBrowser.c
< prev
next >
Wrap
Text File
|
1996-07-02
|
7KB
|
314 lines
/* FindBrowser.c
* Look for and launch a Web browser that supports the GetURL event
* Copyright ©1996 Michael D. Crawford. All Rights Reserved.
* You may use this code on the condition that you read the following web page:
* http://www.scruznet.com/~crawford/WordServices/wdsvindex.html
* 1 Jul 96 Mike Crawford crawford@scruznet.com
*/
#include "FindBrowser.h"
#include "FindProcess.h"
OSErr LookForProcess( OSType creator, Boolean *gotItPtr );
OSErr LaunchTheApp( FSSpecPtr specPtr );
OSErr SearchVolForBrowser( short vRef,
Boolean *gotItPtr,
OSType **creators,
short numCreators,
FSSpecPtr specPtr,
OSType *creatorPtr );
OSErr FindBrowser( OSType *creatorPtr )
{
OSType **creators;
OSErr err;
short i;
short numCreators;
Boolean gotIt;
ProcessSerialNumber psn;
ProcessInfoRec pInfo;
FSSpec fSpec;
Str255 procName;
VolumeParam vPB;
*creatorPtr = 'null';
creators = (OSType**)GetResource( 'Cr8r', 128 );
if ( !creators )
return resNotFound;
numCreators = GetHandleSize( (Handle)creators ) / sizeof( OSType );
// Search the running processes for one we know about
for ( i = 0; i < numCreators; i++ ){
gotIt = FindAProcess( (*creators)[ i ],
&psn,
&pInfo,
&fSpec,
procName );
if ( gotIt ){
*creatorPtr = (*creators)[ i ];
return noErr;
}
}
vPB.ioCompletion = (IOCompletionUPP)NULL;
vPB.ioVolIndex = 1;
vPB.ioNamePtr = (StringPtr)NULL;
do {
err = PBGetVInfoSync( (ParamBlockRec*)&vPB );
if ( err == nsvErr )
return noErr; // Out of volumes to search, haven't found any browsers
if ( err )
return err;
err = SearchVolForBrowser( vPB.ioVRefNum,
&gotIt,
creators,
numCreators,
&fSpec,
creatorPtr );
if ( gotIt ){
err = LaunchTheApp( &fSpec );
return err;
}
vPB.ioVolIndex++;
}while( !err && !gotIt );
return noErr;
}
OSErr SearchVolForBrowser( short vRef,
Boolean *gotItPtr,
OSType **creators,
short numCreators,
FSSpecPtr specPtr,
OSType *creatorPtr )
{
short i;
DTPBRec dPB;
short refNum;
Str255 name;
FInfo fndrInfo;
OSErr err;
*gotItPtr = false;
dPB.ioNamePtr = (StringPtr)NULL;
dPB.ioVRefNum = vRef;
err = PBDTGetPath( &dPB );
if ( err )
return err;
refNum = dPB.ioDTRefNum;
dPB.ioCompletion = (IOCompletionUPP)NULL;
dPB.ioNamePtr = name;
for ( i = 0; i < numCreators; i++ ){
dPB.ioFileCreator = (*creators)[ i ];
dPB.ioIndex = 1;
do{
err = PBDTGetAPPL( &dPB, false );
if ( err == afpItemNotFound )
break;
if ( err )
return err;
// We got the application info, but it is possible that the application
// has been deleted without the desktop file being updated. Check to
// see that the file is still there.
err = HGetFInfo( vRef, dPB.ioAPPLParID, name, &fndrInfo );
if ( !err ){
err = FSMakeFSSpec( vRef, dPB.ioAPPLParID, name, specPtr );
if ( err )
return err;
*creatorPtr = dPB.ioFileCreator;
*gotItPtr = true;
return noErr;
}
}while( !err );
}
return noErr;
}
OSErr LaunchTheApp( FSSpecPtr specPtr )
{
OSErr err;
Boolean changed;
AppleEvent launchEvent;
AppleEvent replyEvent;
AEDesc aliasDesc;
AEDesc folderDesc;
FSSpec folderSpec;
AEDesc finderAddr;
DescType finderSig;
AliasHandle fAliasHdl;
AliasHandle appAliasHdl;
AEDescList aliasList;
// Launch the browser by sending an Open Selection apple event to the Finder.
// We need to do this so that the process shows up in the application menu, so that
// we see zoomrects on launch, and so that the application's icon is dimmed in its
// Finder window
// Taken from Writeswell Jr.'s LaunchSpeller in DoChecking.c
/* make an alias for the parent folder */
err = FSMakeFSSpec( specPtr->vRefNum,
specPtr->parID,
(StringPtr)NULL,
&folderSpec );
if ( err ){
return err;
}
err = NewAlias( (FSSpecPtr)NULL, &folderSpec, &fAliasHdl );
if ( err ){
return err;
}
/* Create the event to send to the Finder */
finderSig = 'MACS'; /* Creator code of finder; type is 'FNDR' */
err = AECreateDesc( typeApplSignature,
(Ptr)&finderSig,
sizeof( finderSig ),
&finderAddr );
if ( err ){
return err;
}
err = AECreateAppleEvent( kAEFinderEvents,
kAEOpenSelection,
&finderAddr,
kAutoGenerateReturnID,
kAnyTransactionID,
&launchEvent );
if ( err ){
return err;
}
err = AEDisposeDesc( &finderAddr );
if ( err ){
return err;
}
/* Insert the folder alias record as the direct object of the batch event */
/* First make a descriptor of the alias */
HLock( (Handle) fAliasHdl );
err = AECreateDesc( typeAlias,
(Ptr)*fAliasHdl,
(*fAliasHdl)->aliasSize,
&folderDesc );
HUnlock( (Handle) fAliasHdl );
DisposHandle( (Handle) fAliasHdl );
if ( err ){
return err;
}
err = AEPutParamDesc( &launchEvent,
keyDirectObject,
&folderDesc );
if ( err ){
return err;
}
err = AEDisposeDesc( &folderDesc );
if ( err ){
return err;
}
/* Put the application alias on the event */
err = NewAlias( (FSSpecPtr)NULL, specPtr, &appAliasHdl );
if ( err ){
return err;
}
HLock( (Handle) appAliasHdl );
err = AECreateDesc( typeAlias,
(Ptr)*appAliasHdl,
(*appAliasHdl)->aliasSize,
&aliasDesc );
HUnlock( (Handle) appAliasHdl );
DisposeHandle( (Handle)appAliasHdl );
if ( err ){
return err;
}
/* Now make a list of the alias descriptor. There is only one element in this
* list
*/
err = AECreateList( (Ptr)NULL, (Size)0, false, &aliasList );
if ( err ){
return err;
}
err = AEPutDesc( &aliasList, 1L, &aliasDesc );
if ( err ){
return err;
}
err = AEDisposeDesc( &aliasDesc );
if ( err ){
return err;
}
err = AEPutParamDesc( &launchEvent,
keySelection,
&aliasList );
if ( err ){
return err;
}
err = AEDisposeDesc( &aliasList );
if ( err ){
return err;
}
err = AESend( &launchEvent,
&replyEvent,
kAEWaitReply + kAECanInteract, /* Don't allow later switch */
kAENormalPriority,
1800, // Thirty seconds; browser can take a long time to initialize
(AEIdleUPP)NULL,
(AEFilterUPP)NULL );
if ( err ){
return err;
}
err = AEDisposeDesc( &launchEvent );
if ( err ){
return err;
}
err = AEDisposeDesc( &replyEvent );
if ( err ){
return err;
}
return noErr;
}